<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
  <head>    
    <title>Estructura BCK</title>    
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <link href="../../styles.css" rel="stylesheet">
    <link rel="icon" href="../../images/icon.png">
	</head>
	<body>
		<div id="top">
      <h1>Estructura BCK</h1> 
		</div>
    <div id="main">
      <h2>Contenido</h2>
      <div class="contents">
        <ol>        
          <li><a href="#intro">Introducci&oacute;n</a></li>
          <li><a href="#func">Funcionamiento</a></li>
          <li><a href="#defs">Definiciones</a></li>
          <li><a href="#struct">Estructura</a></li>
          <li><a href="#example">Ejemplo</a></li>
        </ol>
      </div>
      <h2 id="intro">Introducci&oacute;n</h2>
      <div class="contents">
        <p>El tipo de archivo <b>BCK</b> es un archivo que se puede conseguir en SMG. Este se encarga de guardar la informaci&oacute;n de animaci&oacute;n esquel&eacute;tica en los modelos 3D. Es decir, almacena valores de escalamiento, rotaci&oacute;n y traslaci&oacute;n para los distintos huesos de un modelo en 3D. Al juego leer este tipo de archivo, aplica las transformaciones correspondientes a cada hueso del modelo 3D y estos huesos a su vez deforman los vertices que estan asignados a ellos mostrando el efecto final de la animaci&oacute;n. Un ejemplo de su uso es en el modelo <code>ChooChooTrain</code> para animar la rotaci&oacute;n de las ruedas.</p>
        <br>
        <img style="width: 70%;" src="../../images/bck/choochootrain-run.gif" alt="Image could not be loaded.">
        <p class="idtext">Vid. 1: <code>choochootrain.bdl</code> con la animaci&oacute;n <code>run.bck</code> vista en <code><a href="https://github.com/VTXG/noclip.smg">noclip.smg</a></code></p>
        <br>
      </div>
      <h2 id="intro">Funcionamiento</h2>
      <div class="contents">
        <p>Los modelos 3D de SMG tienen un m&eacute;todo para volverse <i>m&oacute;viles</i>: Contienen varios <i>sistemas de referencia</i> en diferentes secciones del modelo que pueden o no estar determinados por otro sistema de referencia (sistema padre). A estos sistemas de referencia se pueden <i>enlazar</i> v&eacute;rtices del modelo 3D y se tiene la capacidad de especificar el <i>peso</i> de este enlace para cada v&eacute;rtice en el proceso de creaci&oacute;n del modelo. Al modificar las propiedades de uno de estos sistemas, y con la existencia de v&eacute;rtices enlazados a este sistema, se pueden transferir estas modificaciones al sistema como modificaciones a los vertices.</p>
        <br>
        <img src="../../images/bck/bck-func1.gif" alt="Image could not be loaded.">
        <br>
        <p>En el &aacute;rea de modelado 3D a estos sistemas de referencia se les denomina "huesos" ya que es usual animar movimientos de seres vivos. La idea de una jerarqu&iacute;a puede verse mejor aqu&iacute; dado que el movimiento de un hueso va a depender del movimiento del hueso que "lo contiene".</p>
        <br>
        <img src="../../images/bck/bck-func2.gif" alt="Image could not be loaded.">
        <br>
        <p>La &uacute;nica restricci&oacute;n en esta estructura es que los modelos deben tener un hueso padre absoluto/ra&iacute;z (sistema de referencia principal) a partir del cual todos los dem&aacute;s huesos estan sujetos.</p>
        <br>
        <img src="../../images/bck/bck-func3.png" alt="Image could not be loaded.">
        <br>
        <p>La informaci&oacute;n guardada en los archivos BCK es de escalamiento, rotaci&oacute;n y translaci&oacute;n para cada hueso en el modelo 3D. Cada grupo de valores para cada hueso est&aacute; especificado para el sistema de referencia que va con dicho hueso. Todos los huesos del modelo deben tener al menos un dato de animaci&oacute;n para que el archivo sea compatible con el modelo.</p>
      </div>
      <h2 id="defs">Definiciones</h2>
      <div class="contents">
        <ul>
          <li><b>Secci&oacute;n ANK1</b>: &uacute;nica secci&oacute;n de los archivos BCK que contiene todos los datos de la animaci&oacute;n de esqueleto.</li>
          <li>
            <p><b>Modo de repetici&oacute;n</b>: Entero de 8 bits que especifica como se repite la animaci&oacute;n. Las opciones son:</p>
            <ul>
              <li><b>0</b>: Se reproduce la animaci&oacute;n una sola vez y se mantiene el &uacute;ltimo cuadro de la animaci&oacute;n cargado en el modelo.</li>
              <li><b>1</b>: Se reproduce la animaci&oacute;n una sola vez y se mantiene el primer cuadro de la animaci&oacute;n cargado en el modelo.</li>
              <li><b>2</b>: Se reproduce la animaci&oacute;n infinitas veces hacia adelante.</li>
              <li><b>3</b>: Se reproduce la animaci&oacute;n una vez hacia adelante y una vez hacia atr&aacute;s.</li>
              <li><b>4</b>: Se reproduce la animaci&oacute;n infinitas veces hacia adelante y hacia atr&aacute;s.</li>
            </ul>
          </li>
          <li>
            <p><b>Duraci&oacute;n de la animaci&oacute;n</b>: Entero de 16 bits que indica la duraci&oacute;n de la animaci&oacute;n de esqueleto. Este n&uacute;mero dice que tantos datos de la animaci&oacute;n de cada hueso usar.</p>
            <ul>
              <li><b>Si faltan datos de animaci&oacute;n, para un hueso:</b> Se agarra el valor del &uacute;ltimo cuadro disponible y se mantiene hasta el final de la animaci&oacute;n.</</li>
              <li><b>Si sobran datos de animaci&oacute;n para un hueso:</b> Se agarran los datos hasta que se termine la animaci&oacute;n (se ignoran los datos posteriores).</li>
            </ul>
          <li>
            <p><b>Datos de animaci&oacute;n de un hueso</b>: Es una estructura de datos con 3 enteros de 16 bits. Existen 9 de ellas por cada hueso, una para cada tipo de variable a animar: escalamiento / rotaci&oacute;n / translaci&oacute;n XYZ.</p>
            <br>
            <p>En el archivo BCK aparecen en el orden: Escalamiento en X, Rotaci&oacute;n en X, Translaci&oacute;n en X, Escalamiento en Y, Rotaci&oacute;n en Y, Translaci&oacute;n en Y, Escalamiento en Z, Rotaci&oacute;n en Z y Translaci&oacute;n en Z.</p>
            <br>
            <p>Los 3 enteros de 16 bits tienen las siguientes funciones:</p></p>
            <ul>
              <li>
                <p><b>N&uacute;mero de cuadros de referencia</b>: Indica el n&uacute;mero de cuadros de referencia (cuadros clave/keyframes) que se tienen para la animaci&oacute;n.</p>
                <img src="../../images/bck/kf-count.png" alt="Image could not be loaded.">
              </li>
              <li>
                <p><b>&Iacute;ndice de los datos</b>: posici&oacute;n de los datos en el arreglo correspondiente (arreglo de escalamiento/rotaci&oacute;n/translaci&oacute;n).</p>
                <img src="../../images/bck/data-index.png" alt="Image could not be loaded.">
              </li>
              <li><b>Modo de interpolaci&oacute;n</b>:
                <ul>
                  <li>
                    <p><code>0</code>: Se usa la misma pendiente para la llegada y salida al valor num&eacute;rico del cuadro en la interpolaci&oacute;n (puede pensarse que es una curva <i>suave</i>).</p>
                    <img src="../../images/bck/interp-soft.png" alt="Image could not be loaded.">
                  </li>
                  <li>
                    <p><code>1</code>: Se usa una pendiente para la llegada y otra pendiente para la salida al valor num&eacute;rico del cuadro en la interpolaci&oacute;n (<i>pendientes personalizadas</i>).</p>
                    <img src="../../images/bck/interp-custom.png" alt="Image could not be loaded.">
                  </li>
                </ul>
              </li>
            </ul>
            <br>
            <p>La expresi&oacute;n de interpolaci&oacute;n usada entre 2 cuadros clave es la del <a href="model3.html#cubic-hermite-spline">Spline C&uacute;bico de Hermite</a> asumiendo que <code>t0 = 0 y tf = 1</code>.</p>
            <br>
            <p>Dependiendo de los datos de animaci&oacute;n de un hueso, hay 3 formas de leer el arreglo de animaci&oacute;n correspondiente:</p>
            <ul>
              <li><b>El n&uacute;mero de cuadros clave es <code>1</code></b>: La variable a animar no tiene animaci&oacute;n. S&oacute;lo se lee un dato del arreglo correspondiente (en el &iacute;ndice especificado) y ese dato especifica el valor de esta variable durante toda la animaci&oacute;n.</li>
              <li><b>El n&uacute;mero de cuadros clave es mayor que <code>1</code> y el modo de interpolaci&oacute;n es <code>0</code> (suave)</b>: Se leen 3 datos por cuadro clave. El primero se refiere al tiempo, el segundo al valor de la variable en ese tiempo y el tercero representa la pendiente de llegada y salida de ese punto para usarse en la expresi&oacute;n de interpolaci&oacute;n.</li>
              <li><b>El n&uacute;mero de cuadros clave es mayor que <code>1</code> y el modo de interpolaci&oacute;n es <code>1</code> (personalizado)</b>: Se leen 4 datos por cuadro clave. El primero se refiere al tiempo, el segundo al valor de la variable en ese tiempo, el tercero representa la pendiente de llegada al punto y el cuarto representa la pendiente de salida de ese punto.</li>
            </ul>
            <br>
            <img src="../../images/bck/bone-anim-data-modes.png" alt="Image could not be loaded.">
            <br>
          </li>
          <li><b>Arreglo de escalamiento</b>: Arreglo de n&uacute;meros de punto flotante de 32 bits que contiene los datos de animaci&oacute;n de escalamiento XYZ de todos los huesos.</li>
          <li>
            <p><b>Arreglo de rotaci&oacute;n</b>: Arreglo de enteros con signo de 16 bits que contiene los datos de animaci&oacute;n de rotaci&oacute;n XYZ de todos los huesos. El entero se convierte en un &aacute;ngulo usando la siguiente formula (y el dato de <b>shift izquierdo</b> que viene en el mismo archivo BCK):</p>
            <img src="../../images/bck/get-real-angle.png" alt="Image could not be loaded.">
            <br>
            <p>B&aacute;sicamente mapean los &aacute;ngulos positivos entre <code>0x0000</code> y <code>0x7FFF</code> (<code>0&deg;</code> a <code>(180 &lt;&lt; rot_lshift)&deg;</code>) y los negativos entre <code>0x8000</code> y <code>0xFFFF</code> (<code>-(180 &lt;&lt; rot_lshift)&deg;</code> a <code>-0&deg;</code>).</p>
            <br>
            <p>Las pendientes estan especificadas en el mismo sistema que los &aacute;ngulos codificados (estan codificadas) y el tiempo est&aacute; guardado sin codificaci&oacute;n.</p>
          </li>
          <li><b>Arreglo de translaci&oacute;n</b>: Arreglo de n&uacute;meros de punto flotante de 32 bits que contiene los datos de animaci&oacute;n de translaci&oacute;n XYZ de todos los huesos.</li>
        </ul>
      </div>
      <h2 id="struct">Estructura</h2>
      <div class="contents">
        <p><b>Encabezado</b></p>
        <br>
        <table>
          <tr>
            <th>Nombre</th>
            <th>Tama&ntilde;o</th>
            <th>Descripci&oacute;n</th>
          </tr>
          <tr>
            <td>Magia</td>
            <td>4 bytes</td>
            <td><code>J3D1</code> (Big Endian) o <code>1D3J</code> (Little Endian).</td>
          </tr>
          <tr>
            <td>Tipo</td>
            <td>4 bytes</td>
            <td><code>bck1</code> (Big Endian) o <code>1kcb</code> (Little Endian).</td>
          </tr>
          <tr>
            <td>Tama&ntilde;o del archivo</td>
            <td>4 bytes</td>
            <td>En bytes.</td>
          </tr>
          <tr>
            <td>N&uacute;mero de secciones</td>
            <td>4 bytes</td>
            <td>Parece ser siempre <code>0x1</code>.</td>
          </tr>
          <tr>
            <td>Desconocido 1</td>
            <td >16 bytes</td>
            <td>Parecen ser siempre 16 <code>0xFF</code> bytes.</td>
          </tr>
        </table>
        <br>
        <p><b>Secci&oacute;n ANK1</b></p>
        <br>
         <table>
          <tr>
            <th>Nombre</th>
            <th>Tama&ntilde;o</th>
            <th>Descripci&oacute;n</th>
          </tr>
          <tr>
            <td>Magia</td>
            <td>4 bytes</td>
            <td><code>ANK1</code> (Big Endian) o <code>1KNA</code> (Little Endian).</td>
          </tr>
          <tr>
            <td>Tama&ntilde;o de la secci&oacute;n</td>
            <td>4 bytes</td>
            <td>En bytes.</td>
          </tr>
          <tr>
            <td>Modo de repetici&oacute;n</td>
            <td>1 byte</td>
            <td><code>0x00</code>, <code>0x01</code>, <code>0x02</code>, <code>0x03</code> o <code>0x04</code>.</td>
          </tr>
          <tr>
            <td>Shift izquierdo para la rotaci&oacute;n</td>
            <td>1 byte</td>
            <td>El valor num&eacute;rico que especifica el n&uacute;mero de shifts izquierdos que hay hacerle a los valores de rotaci&oacute;n guardados para obtener el valor que realmente se guard&oacute;. Ver f&oacute;mula de arriba.</td>
          </tr>
          <tr>
            <td>Duraci&oacute;n de la animaci&oacute;n</td>
            <td>2 bytes</td>
            <td>Especificada en cuadros.</td>
          </tr>
          <tr>
            <td>N&uacute;mero de huesos</td>
            <td>2 bytes</td>
            <td>N&uacute;mero de huesos en el archivo BCK para animar.</td>
          </tr>
          <tr>
            <td>Tama&ntilde;o del arreglo de escalamiento</td>
            <td>2 bytes</td>
            <td>Longitud del arreglo en donde se guardan los valores de animaci&oacute;n de escalamiento de los huesos.</td>
          </tr>
          <tr>
            <td>Tama&ntilde;o del arreglo de rotaci&oacute;n</td>
            <td>2 bytes</td>
            <td>Longitud del arreglo en donde se guardan los valores de animaci&oacute;n de rotaci&oacute;n de los huesos.</td>
          </tr>
          <tr>
            <td>Tama&ntilde;o del arreglo de translaci&oacute;n</td>
            <td>2 bytes</td>
            <td>Longitud del arreglo en donde se guardan los valores de animaci&oacute;n de translaci&oacute;n de los huesos.</td>
          </tr>
          <tr>
            <td>Posici&oacute;n de los datos de animaci&oacute;n de cada hueso</td>
            <td>4 bytes</td>
            <td>Respecto al inicio de la secci&oacute;n. Parece ser siempre <code>0x40</code>.</td>
          </tr>
          <tr>
            <td>Posici&oacute;n del arreglo de escalamiento</td>
            <td>4 bytes</td>
            <td>Respecto al inicio de la secci&oacute;n.</td>
          </tr>
          <tr>
            <td>Posici&oacute;n del arreglo de rotaci&oacute;n</td>
            <td>4 bytes</td>
            <td>Respecto al inicio de la secci&oacute;n.</td>
          </tr>
          <tr>
            <td>Posici&oacute;n del arreglo de translaci&oacute;n</td>
            <td>4 bytes</td>
            <td>Respecto al inicio de la secci&oacute;n.</td>
          </tr>
          <tr>
            <td>Relleno 1</td>
            <td style="white-space: nowrap"><a href="common.html#padding">M&aacute;ximo 31 bytes</a></td>
            <td>Alinea hasta el siguiente byte multiplo de 32.</td>
          </tr>
          <tr style="background-color: #EEEEEE;">
            <td style="white-space: nowrap"><b>Inicio:</b> Datos de animaci&oacute;n de los huesos</td>
            <td colspan="2">(9 * 6 * Número de huesos) bytes</td>
          </tr>
          <tr style="background-color: #EEEEEE;">
            <td colspan="3">
              <table style="margin-left: 2%; width: 98%;">
                <tr style="background-color: #CCCCCC;">
                  <td><b>Inicio:</b> Datos de animaci&oacute;n de un hueso</td>
                  <td colspan="2">(9 * 6) bytes</td>
                </tr>
                <td colspan="3" style="background-color: #CCCCCC;">
                  <table style="margin-left: 2%; width: 98%;">
                    <table>
                      <tr>
                        <td style="white-space: nowrap">Escalamiento en X</td>
                        <td rowspan="9">
                          <table>
                            <tr>
                              <td style="white-space: nowrap">N&uacute;mero de cuadros clave</td>
                              <td style="white-space: nowrap">2 bytes</td>
                              <td>N&uacute;mero de cuadros clave para la animaci&oacute;n de SRT (escalamiento / rotaci&oacute;n / translaci&oacute;n) XYZ del i-&eacute;simo hueso.</td>
                            </tr>
                            <tr>
                              <td>&Iacute;ndice de los datos</td>
                              <td>2 bytes</td>
                              <td>Posici&oacute;n del sub-arreglo correspondiente de SRT con los datos de la animaci&oacute;n de SRT XYZ del i-&eacute;simo hueso.</td>
                            </tr>
                            <tr>
                              <td>Modo de interpolaci&oacute;n</td>
                              <td>2 bytes</td>
                              <td><code>0</code> (suave) o <code>1</code> (personalizada).</td>
                            </tr>
                          </table>
                        </td>
                      </tr>
                      <tr><td>Rotaci&oacute;n en X</td></tr>
                      <tr><td>Translaci&oacute;n en X</td></tr>
                      <tr><td>Escalamiento en Y</td></tr>
                      <tr><td>Rotaci&oacute;n en Y</td></tr>
                      <tr><td>Translaci&oacute;n en Y</td></tr>
                      <tr><td>Escalamiento en Z</td></tr>
                      <tr><td>Rotaci&oacute;n en Z</td></tr>
                      <tr><td>Translaci&oacute;n en Z</td></tr>
                    </table>
                <tr style="background-color: #CCCCCC;">
                  <td colspan="3"><b>Final:</b> Datos de animaci&oacute;n de un hueso</td>
                </tr>
              </table>
            </td>
          </tr>
          <tr style="background-color: #EEEEEE;">
            <td colspan="3"><b>Final:</b> Datos de animaci&oacute;n de los huesos</td>
          </tr>
          <tr>
            <td>Relleno 2</td>
            <td><a href="common.html#padding">M&aacute;ximo 31 bytes</a></td>
            <td>Alinea hasta el siguiente byte multiplo de 32.</td>
          </tr>
          <tr style="background-color: #EEEEEE;">
            <td><b>Inicio:</b> Arreglo de escalamiento</td>
            <td colspan="2">(4 * Tamaño del arreglo de escalamiento) bytes</td>
          </tr>
          <tr style="background-color: #EEEEEE;">
            <td colspan="3">
              <table style="margin-left: 2%; width: 98%;">
                <tr>
                  <td>N&uacute;mero[i]</td>
                  <td style="white-space: nowrap">4 bytes (float32)</td>
                  <td>Valor num&eacute;rico que puede representar el tiempo, el valor de escalamiento XYZ en un tiempo o una pendiente.</td>
                </tr>
              </table>
            </td>
          </tr>
          <tr style="background-color: #EEEEEE;">
            <td colspan="3"><b>Final:</b> Arreglo de escalamiento</td>
          </tr>
          <tr>
            <td>Relleno 3</td>
            <td><a href="common.html#padding">M&aacute;ximo 31 bytes</a></td>
            <td>Alinea hasta el siguiente byte multiplo de 32.</td>
          </tr>
          <tr style="background-color: #EEEEEE;">
            <td><b>Inicio:</b> Arreglo de rotaci&oacute;n</td>
            <td colspan="2">(2 * Tamaño del arreglo de rotaci&oacute;n) bytes</td>
          </tr>
          <tr style="background-color: #EEEEEE;">
            <td colspan="3">
              <table style="margin-left: 2%; width: 98%;">
                <tr>
                  <td>N&uacute;mero[i]</td>
                  <td style="white-space: nowrap">2 bytes (s16)</td>
                  <td>Valor num&eacute;rico que puede representar el tiempo, el valor de rotaci&oacute;n XYZ en un tiempo o una pendiente (ver arriba como interpretar los valores num&eacute;ricos guardados).</td>
                </tr>
              </table>
            </td>
          </tr>
          <tr style="background-color: #EEEEEE;">
            <td colspan="3"><b>Final:</b> Arreglo de rotaci&oacute;n</td>
          </tr>
          <tr>
            <td>Relleno 4</td>
            <td><a href="common.html#padding">M&aacute;ximo 31 bytes</a></td>
            <td>Alinea hasta el siguiente byte multiplo de 32.</td>
          </tr>
          <tr style="background-color: #EEEEEE;">
            <td><b>Inicio:</b> Arreglo de translaci&oacute;n</td>
            <td colspan="2">(4 * Tamaño del arreglo de translaci&oacute;n) bytes</td>
          </tr>
          <tr style="background-color: #EEEEEE;">
            <td colspan="3">
              <table style="margin-left: 2%; width: 98%;">
                <tr>
                  <td>N&uacute;mero[i]</td>
                  <td style="white-space: nowrap">4 bytes (float32)</td>
                  <td>Valor num&eacute;rico que puede representar el tiempo, el valor de translaci&oacute;n XYZ en un tiempo o una pendiente.</td>
                </tr>
              </table>
            </td>
          </tr>
          <tr style="background-color: #EEEEEE;">
            <td colspan="3"><b>Final:</b> Arreglo de translaci&oacute;n</td>
          </tr>
          <tr>
            <td>Relleno 5</td>
            <td><a href="common.html#padding">M&aacute;ximo 31 bytes</a></td>
            <td>Alinea hasta el siguiente byte multiplo de 32.</td>
          </tr>
        </table>
      </div>
      <h2 id="example">Ejemplo</h2>
      <div class="contents">
        <p>Estructura coloreada de <code>run.bck</code> en ImHex:</p>
        <br>
        <img src="../../images/bck/example.png">
        <br>
        <p>El archivo se encuentra en <code>ObjectData/ChooChooTrain.arc</code>.</p>
      </div>
      <h2 id="refs">Referencias</h2>
      <div class="contents">
        <ul>
          <li><a href="https://wiki.cloudmodding.com/zgcn/BCK">https://wiki.cloudmodding.com/zgcn/BCK</a></li>
        </ul>
      </div>
    </div>
	</body>
</html>
